const express = require('express')
const app = express();
const apiRouter = require('./router');
const cors = require('cors');
/**
 * CORS 跨域资源共享
 * 使用步骤：
 * 1. 安装cors模块 npm install cors
 * 2. 引入cors模块 const cors = require('cors')
 * 3. 在路由之前设置cors app.use(cors())
 */

/**
 * express支持https请求的操作
 * https请求需要使用https.createServer()方法创建一个https服务器
 * 1. 引入https模块
 * 2. 创建https服务器
 * 3. 监听https请求
 * 4. 设置证书
 * 5. 设置密钥
 * 6. 设置请求处理
 * 7. 启动服务器
 */

/**
 * cors 响应头部设置
 * 1. Access-Control-Allow-Origin：允许访问的域名
 * 2. Access-Control-Allow-Headers：允许的请求头
 *  默认情况下，cors仅支持客户端向服务器发送如下的9个请求头：
    *  Accept、Accept-Language、Content-Language、Content-Type（值仅限于text/plain、multipart/form-data、application/x-www-form-urlencoded 三者之一）、DPR、Downlink、Save-Data、Viewport-Width、Width
    *  如果客户端发送其他请求头，服务器会返回一个预检请求，询问服务器是否允许这个请求
    *  预检请求的请求方法是OPTIONS，预检请求的请求头是Access-Control-Request-Headers
    *  如果客户端向服务器发送了额外的请求头信息，则需要在服务器端，通过 Access-Control-Allow-Headers 对额外的请求头进行声明，否则这次请求会失败！
 * 3. Access-Control-Allow-Methods：允许的请求方法
 *    默认情况下，cors仅支持客户端向服务器发送如下的请求方法：GET、POST、HEAD
 *    如果客户端发送其他请求方法，服务器会返回一个预检请求，询问服务器是否允许这个请求
    *  如果客户端希望通过 PUT、DELETE 等方式请求服务器的资源，则需要在服务器端，通过 Access-Control-Alow-Methods
    *  来指明实际请求所允许使用的 HTTP 方法。
 * 4. Access-Control-Allow-Credentials：是否允许发送Cookie
 */

/**
 * cors请求分类
 * 1. 简单请求: 满足以下两个条件的请求
 *   1. 请求方法是GET、POST、HEAD
 *   2. 请求头信息不超出以下字段：Accept、Accept-Language、Content-Language、Content-Type（值仅限于text/plain、multipart/form-data、application/x-www-form-urlencoded 三者之一）、DPR、Downlink、Save-Data、Viewport-Width、Width
 * 2. 预检请求：不满足以下任何一个条件的请求
 *  1. 请求方法不是GET、POST、HEAD
 *  2. 请求头中包含自定义头部字段
 *  3. 请求头中的Content-Type不是application/x-www-form-urlencoded、multipart/form-data、text/plain
 *  预检请求的在浏览器和服务器正式通信之前，浏览器会先发送一个options请求，询问服务器是否允许这个请求;服务器响应options请求后才会发送真正的请求并携带真实数据
 * 两者区别：
 *  1.简单请求客户端和服务器之间只有一次HTTP通信，而预检请求客户端和服务器之间有两次HTTP通信
 */
app.use((req,res,next)=>{
    res.setHeader('Access-Control-Allow-Origin','*');
    // 当客户端发送额外的请求头时，浏览器会发送一个预检请求，检查服务器是否允许这个请求，并且服务器需要设置允许的请求头
    res.setHeader('Access-Control-Allow-Headers','test');
    res.setHeader('Access-Control-Allow-Methods','*');
    next();
})

/**
 * cors模块的注意事项
 * 1. cors模块必须在路由之前设置
 * 2. cors模块的设置是全局的，会影响所有的路由
 * 3. cors模块主要是服务端设置的，客户端不需要做任何设置
 * 4. cors模块在浏览器中有兼容性问题，不同的浏览器可能会有不同的表现
 */
// app.use(cors());
app.use('/api', apiRouter);

app.listen(8080, () => {
    console.log('server is running at http://localhost:8080')
})